/*
 * Copyright (C) 2008-2010 Oliver Horn.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.funcj.functions;

import com.google.common.base.Function;
import com.googlecode.funcj.Function2;

/**
 * Helper class that provides useful {@code Function}s and {@code Function2}s for integers.
 * <p>
 * Note that these functions accepts not only integers but any {@link Number} objects
 * (which will be converted to an integer internally).
 *
 * @see Function
 * @see Function2
 *
 * @author Oliver Horn
 */
public final class IntegerFunctions {

	private IntegerFunctions() {
	}

	/**
	 * Returns a function which calculates the successor of its {@code Number} argument.
	 */
	public static final Function<Number, Integer> succFunction() {
		return IntSuccFunction.INSTANCE;
	}

	/**
	 * Returns a function which calculates the sum of its {@code Number} arguments.
	 */
	public static final Function2<Number, Number, Integer> addFunction() {
		return IntAddFunction.INSTANCE;
	}

	/**
	 * Returns a function which calculates the minimum of its {@code Number}
	 * arguments.
	 */
	public static final Function2<Number, Number, Integer> minFunction() {
		return IntMinFunction.INSTANCE;
	}

	/**
	 * Returns a function which calculates the maximum of its {@code Number}
	 * arguments.
	 */
	public static final Function2<Number, Number, Integer> maxFunction() {
		return IntMaxFunction.INSTANCE;
	}

	private enum IntSuccFunction implements Function<Number, Integer> {
		INSTANCE;

		public Integer apply(Number arg) {
			return arg.intValue() + 1;
		}
		@Override
		public String toString() {
			return "intSucc";
		}
	}

	private enum IntAddFunction implements Function2<Number, Number, Integer> {
		INSTANCE;

		public Integer apply(Number arg1, Number arg2) {
			return arg1.intValue() + arg2.intValue();
		}
		@Override
		public String toString() {
			return "intAdd";
		}
	}

	private enum IntMinFunction implements Function2<Number, Number, Integer> {
		INSTANCE;

		public Integer apply(Number arg1, Number arg2) {
			return Math.min(arg1.intValue(), arg2.intValue());
		}
		@Override
		public String toString() {
			return "intMin";
		}
	}

	private enum IntMaxFunction implements Function2<Number, Number, Integer> {
		INSTANCE;

		public Integer apply(Number arg1, Number arg2) {
			return Math.max(arg1.intValue(), arg2.intValue());
		}
		@Override
		public String toString() {
			return "intMax";
		}
	}
}
